package com.las.bot.cmd.osu;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONObject;
import com.las.bot.dto.OsuMapDTO;
import com.utils.DateUtils;
import com.utils.JsonUtils;
import com.utils.osu.ApiUtil;
import com.utils.osu.ModUtil;
import com.utils.osu.OSUApi;
import com.jfinal.kit.StrKit;
import com.las.annotation.BotCmd;
import com.las.cmd.BaseCommand;
import com.las.utils.mirai.CmdUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import static com.utils.osu.ModUtil.*;

@BotCmd(funName = "OSU")
public class OsuRecentCommand extends BaseCommand {

    private Logger logger = LoggerFactory.getLogger(OsuRecentCommand.class);

    @Autowired
    private OSUApi osuApi;

    public OsuRecentCommand() {
        super("recent", "", "", "tr", "mr", "cr");
    }

    @Override
    public void execute(Long userId, Long id, Integer type, String command, ArrayList<String> args) {
        String bid;
        String osuName = null;
        int mode = 0;
        if (command.startsWith("tr")) {
            mode = 1;
        } else if (command.startsWith("cr")) {
            mode = 2;
        } else if (command.startsWith("mr")) {
            mode = 3;
        }
        if (args.size() > 0) {
            osuName = args.get(0);
        }
        osuName = osuApi.reset(userId, id, type, osuName);
        if (StrKit.notBlank(osuName)) {
            //重新reset之后，进入recent的方法
            CmdUtil.sendMessage("正在查询玩家：" + osuName + " 的成绩，请稍候...", userId, id, type);
            StringBuilder sb = new StringBuilder();
            List<Map> info = JsonUtils.getArrayByJson(ApiUtil.getRecentApi(osuName, mode), Map.class);
            if (CollectionUtil.isNotEmpty(info)) {
                Map data = info.get(0);
                if(null == data || null == data.get("beatmap_id")){
                    CmdUtil.sendMessage("玩家 " + osuName + " 最近没有数据记录，请检查入参是否正确！", userId, id, type);
                    return;
                }
                bid = data.get("beatmap_id").toString();
                if (!"".equals(bid)) {
                    String score = data.get("score").toString();
                    String maxCombo = data.get("maxcombo").toString();
                    String date = data.get("date").toString();
                    String rank = data.get("rank").toString();
                    //反转mod
                    String modStr;
                    int mods = Integer.parseInt(data.get("enabled_mods").toString());
                    if (32768 == mods || 65536 == mods || 131072 == mods || 262144 == mods || 524288 == mods || 16777216 == mods) {
                        mods = 0;
                        modStr = "mania特殊mod(Keys)";
                    } else {
                        modStr = ModUtil.convertMOD(mods).keySet().toString().replaceAll("\\[", "").replaceAll("]", "").replaceAll("，", "").replaceAll(",", "");
                    }
                    //计算acc
                    int count50 = Integer.parseInt(data.get("count50").toString());
                    int count100 = Integer.parseInt(data.get("count100").toString());
                    int count300 = Integer.parseInt(data.get("count300").toString());
                    int countmiss = Integer.parseInt(data.get("countmiss").toString());
                    int countkatu = Integer.parseInt(data.get("countkatu").toString());
                    int countgeki = Integer.parseInt(data.get("countgeki").toString());
                    double acc = 0;
                    switch (mode) {
                        case 0:
                            acc = (count300 * 300.0 + count100 * 100.0 + count50 * 50.0) / ((count300 + count100 + count50 + countmiss) * 300);
                            break;
                        case 1:
                            acc = (count300 + count100 * 0.5) / (count300 + count100 + countmiss);
                            break;
                        case 2:
                            int base = count300 + count100 + count50;
                            acc = (double) base / (base + (countmiss + countkatu));
                            break;
                        case 3:
                            acc = (double) (count50 * 50 + count100 * 100 + countkatu * 200 + (count300 + countgeki) * 300) / ((count300 + count100 + count50 + countmiss + countkatu + countgeki) * 300);
                            break;
                        default:
                            break;
                    }
                    double accS = Double.parseDouble(acc((acc * 100) + ""));
                    sb.append("歌谱：").append("https://osu.ppy.sh/b/").append(bid).append("\n");
                    sb.append("模式：").append(getModeName(mode)).append("\n");
                    sb.append("玩家：").append(osuName).append("\n");
                    //插入新需求，把歌曲难度以及歌曲名信息都展示出来
                    OsuMapDTO osuMap = null;
                    if (StrKit.notBlank(bid)) {
                        final String url = "https://osu.ppy.sh/b/" + bid;
                        JSONObject obj = osuApi.getMap(url, 0L, Long.parseLong(bid), true);
                        osuMap = JsonUtils.getObjectByJson(obj.toJSONString(), OsuMapDTO.class);
                        if (null != osuMap) {
                            sb.append("曲目：").append(osuMap.getTitle()).append("\n");
                            sb.append("难度：").append(acc(String.valueOf(osuMap.getDifficultyRating())));
                            if (StrKit.notBlank(modStr)) {
                                sb.append("（").append(modStr).append("）\n");
                            } else {
                                sb.append("\n");
                            }
                        }
                    }
                    sb.append("分数：").append(fen(score)).append("\n");
                    sb.append("最高连击：").append(maxCombo).append("      ");
                    sb.append("评价：").append(rank).append("\n");
                    sb.append("Acc：").append(accS).append("%").append("\n");
                    Date d = DateUtils.formatToDate(DateUtils.HOUR_24, date);
                    sb.append("Date：").append(DateUtils.formatToString(DateUtils.HOUR_24, DateUtils.addHour(d, 8))).append("\n");
                    double pp = -1;
                    List<Map> scoreList = JsonUtils.getArrayByJson(ApiUtil.getScoreApi(osuName, mode, bid), Map.class);
                    if (CollectionUtil.isNotEmpty(scoreList)) {
                        for (Map map : scoreList) {
                            if (String.valueOf(mods).equals(map.get("enabled_mods").toString())
                                    && score.equals(map.get("score").toString())
                                    && rank.equals(map.get("rank").toString())
                                    && maxCombo.equals(map.get("maxcombo").toString())) {
                                if (null != map.get("pp")) {
                                    pp = Double.parseDouble(map.get("pp").toString());
                                    break;
                                }

                            }
                        }

                    }
                    //插入新需求，把#1的最高PP展示出来
                    if (null != osuMap) {
                        //有MOD的需要调API查询最高忘记加了MOD获得的PP
                        String json = ApiUtil.getScoreWithMod(mods, mode, osuMap.getBid() + "");
                        if (StrKit.notBlank(json)) {
                            List<JSONObject> list = JsonUtils.getArrayByJson(json, JSONObject.class);
                            if (CollectionUtil.isNotEmpty(list)) {
                                sb.append("\n本曲#1的PP：").append(list.get(0).getDouble("pp"));
                            }
                        } else {
                            sb.append("\n本曲#1的PP：").append(osuMap.getMaxPp());
                        }
                    }
                    if (-1 == pp) {
                        sb.append("\n您玩得太菜了，无PP记录");
                    } else {
                        sb.append("\n您获得的PP：").append(pp);
                    }
                    CmdUtil.sendMessage(sb.toString(), userId, id, type);
                } else {
                    CmdUtil.sendMessage("玩家 " + osuName + " 最近没有数据记录，请检查入参是否正确！", userId, id, type);
                }
            } else {
                CmdUtil.sendMessage("玩家 " + osuName + " 最近没有数据记录，请快去玩一首曲子吧！", userId, id, type);
            }
        }
    }


}
